<template>
    <div class="three"></div>
</template>

<script>
  import * as THREE from 'three';
  import * as dat from 'dat.gui';
  import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';

  export default {
    name: "FoundationDitch",
    components: {},
    data() {
      return {
        camera: null,
        scene: null,
        renderer: null,
        mesh: null,
        controls: {
          scale: 2,
          rotateY: 0,
          translateX: 0,
          translateY: 0
        },
        intersectObj: null
      }
    },

    mounted() {
      this.init();
    },

    methods: {
      init() {
        this.scene = new THREE.Scene();
        this.div = document.querySelector(".three");
        this.width = this.div.clientWidth;
        this.height = this.div.clientHeight;
        this.raycaster = new THREE.Raycaster();  // 鼠标拾取
        this.mouse = new THREE.Vector2();
        this.initGeometry();
        this.initLight();
        this.initCamera();
        this.initRenderer();
        // this.initFbxLoader();
        this.renderDatGui();
        this.render();
      },

      // 创建几何结构
      initGeometry() {
        // 线
        let geometry = new THREE.Geometry();
        let material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
        let color = new THREE.Color(0xff0000);
        geometry.vertices.push(
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(100, 0, 0),
        );
        geometry.colors.push(color);
        let line = new THREE.Line(geometry, material);
        this.scene.add(line);

        // 矩形 渐变
        // let geometry = new THREE.PlaneGeometry(200, 200, 2, 3);
        // let material = new THREE.MeshBasicMaterial({
        //   vertexColors: THREE.VertexColors,
        //   wireframe: true,   // 是否以线框绘制
        // });
        // let faces = geometry.faces;
        // let color1 = new THREE.Color(0x00900f);
        // let color2 = new THREE.Color(0x049f0f);
        // let color3 = new THREE.Color(0x0900ff);
        // for (let i = 0; i < faces.length; i++) {
        //   let index = faces[i];
        //   index.vertexColors[0] = color1;
        //   index.vertexColors[1] = color2;
        //   index.vertexColors[2] = color3;
        // }
        // let mesh = new THREE.Mesh(geometry, material);
        // this.scene.add(mesh);


        // 三角形
        // let geometry = new THREE.Geometry();
        // let material = new THREE.MeshBasicMaterial({
        //   vertexColors: THREE.VertexColors,
        //   wireframe: false
        // });
        // let color1 = new THREE.Color(0x00900f);
        // let color2 = new THREE.Color(0x049f0f);
        // let color3 = new THREE.Color(0x0900ff);
        // geometry.vertices.push(
        //   new THREE.Vector3(100, 0, 0),
        //   new THREE.Vector3(0, 100, 0),
        //   new THREE.Vector3(-100, 0, 0)
        // );
        //
        // let face = new THREE.Face3(0, 1, 2);
        // face.vertexColors[0] = color1;
        // face.vertexColors[1] = color2;
        // face.vertexColors[2] = color3;
        // geometry.faces.push(face);
        // let mesh = new THREE.Mesh(geometry, material);
        // this.scene.add(mesh);
      },

      // 创建光源
      initLight() {
        // 平行光
        var point = new THREE.DirectionalLight(0xc29e5e);
        point.position.set(0, 400, 100);
        this.scene.add(point);

        // 环境光 颜色设置为`0xffffff`,强度系数设置为0.5
        var ambient = new THREE.AmbientLight(0xd9b26e, 0.06);
        this.scene.add(ambient);
      },

      // 创建相机
      initCamera() {
        var k = this.width / this.height;
        var s = 300; // 三维场景显示范围控制系数，系数越大，显示的范围越大
        var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 10000); // 正投影相机
        this.camera = camera;
        camera.position.set(800, 800, 800);
        camera.lookAt(this.scene.position);
      },

      // 创建渲染器对象
      initRenderer() {
        // antialias  渲染器是否需要高质量渲染（高质量渲染没有锯齿，如果数据量大可以改为 false）
        var renderer = new THREE.WebGLRenderer({ antialias: false });
        this.renderer = renderer;
        renderer.setSize(this.width, this.height);   // 设置渲染区域尺寸
        renderer.setClearColor(0xf0f0f0, 1);
        this.div.appendChild(renderer.domElement);
      },

      initFbxLoader() {
        let filePath = "/static/module/";
        let fbxLoader = new FBXLoader().setPath(filePath);
        let that = this;
        this.group = new THREE.Group();
        fbxLoader.load('gongdi.fbx', function (object) {
          that.object = object;
          object.scale.multiplyScalar(0.4);    // 缩放模型大小
          object.position.set(-40, 0, 150);
          object.rotateX(-1.53);  // 让模型与z轴平行
          object.traverse(function ( child ) {
            if (child.isMesh) {
              child.castShadow = true;
              child.receiveShadow = true;
            }
          });
          that.group.add(object);
          that.scene.add(that.group);

          // 计算模型的 min  max 坐标  把中心坐标点放到模型的中心点
          // let box = new THREE.Box3().setFromObject(object);
          // console.log(box);
          // box.center(object.position);
          // object.position.multiplyScalar(-1);
          // box.center(this.group.position);

          that.onMosueClick(object);
        }, function (event) {
          // 加载模型的进度
          if (event.lengthComputable) {
            let p = event.loaded / event.total * 100;
            // console.log(p);
          }
        });
      },

      onMosueClick(object) {
        this.renderer.domElement.addEventListener('click', (event) => {
          // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 到 +1)
          this.mouse.x = (event.clientX / this.width) * 2 - 1.025;
          this.mouse.y = -(event.clientY / this.height) * 2 + 1.32;

          // 通过摄像机和鼠标位置更新射线
          this.raycaster.setFromCamera( this.mouse, this.camera );
          // 计算物体和射线的焦点
          let intersects = this.raycaster.intersectObjects( object.children , true);

          if (intersects && intersects.length > 0) {
            if (this.isClickFBXLoader(intersects[0].object)) {
              if (this.intersectObj) {
                this.intersectObj.material.color.setHex(0xCCC8C2);  // 设置为默认颜色
              }
              this.intersectObj = intersects[0].object;
              this.intersectObj.faceIndex = intersects[0].faceIndex;
              this.intersectObj.currentHex = this.intersectObj.material.emissive.getHex();  // 获取默认颜色
              this.intersectObj.material.color.setHex(0xFF81B4);  // 设置为选中的颜色
            }
          }
        })
      },

      // 判断是否点击的是模型的柱子
      isClickFBXLoader(object) {
        if (!(object.name.indexOf("楼板") !== -1)) {
          return object;
        } else {
          return null;
        }
      },

      renderDatGui() {
        var gui = new dat.GUI();
        gui.domElement.style = 'position:absolute; top:80px; right:4px';
        gui.add(this.controls, 'scale', 2, 16).name("缩放").step(0.1);
        gui.add(this.controls, 'rotateY', -8, 8).name("旋转").step(0.1);
        gui.add(this.controls, 'translateX', -2500, 2500).name("平移-横向");
        gui.add(this.controls, 'translateY', -3000, 3000).name("平移-纵向");
        this.div.appendChild(gui.domElement);
      },

      // 渲染模型
      render() {
        this.renderer.render(this.scene, this.camera);
        if (this.object) {
          // 控制缩放
          this.group.scale.set(this.controls.scale, this.controls.scale, this.controls.scale);
          // 控制旋转
          this.group.rotation.y = this.controls.rotateY;
          // 横向平移
          this.group.position.z = -this.controls.translateX;
          this.group.position.x = this.controls.translateX;
          // 纵向平移
          this.group.translateX(this.controls.translateY);
          this.group.translateZ(this.controls.translateY);
        }
        requestAnimationFrame(this.render);
      },
    }
  }
</script>

<style scoped lang="scss">
  .three {
    height: 500px;
  }
  img{
    color: #f62c2c;
  }
</style>
